package com.blank.shop.sentinel;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * <br/>Date 2021/8/30
 * <br/>Time 9:46:37
 *
 * @author _blank
 */
@Slf4j
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class ShopAlibabaSentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShopAlibabaSentinelApplication.class, args);
    }

    /*
     * 流控规则：服务限流
     * 熔断规则：服务熔断
     * 热点规则：热点Key
     */

    @GetMapping(path = {"print-aa"})
    public ResponseEntity<String> printAa() {
        return ResponseEntity.ok("print aa!");
    }

    @GetMapping(path = {"print-bb"})
    public ResponseEntity<String> printBb() {
        return ResponseEntity.ok("print bb!");
    }

    @GetMapping(path = {"test-hot-key"})
    @SentinelResource(value = "test-hot-key", blockHandler = "testHotKeyBlockHandler")
    public ResponseEntity<String> testHotKey(@RequestParam(required = false) String p1, @RequestParam(required = false) String p2) {
        return ResponseEntity.ok("test-hot-key: p1: " + p1 + ", p2: " + p2);
    }

    public ResponseEntity<String> testHotKeyBlockHandler(String p1, String p2, BlockException e) {
        log.error(e.getMessage(), e);
        return ResponseEntity.ok("test-hot-key-block-handler: p1: " + p1 + ", p2: " + p2);
    }

    @GetMapping(path = {"print-cc"})
    @SentinelResource(value = "print-cc", blockHandlerClass = {GlobalBlockHandler.class}, blockHandler = "handlerException")
    public ResponseEntity<String> printCc() {
        return ResponseEntity.ok("print cc!");
    }

    @GetMapping(path = {"print-dd"})
    @SentinelResource(
            value = "print-dd"
            , blockHandlerClass = {GlobalBlockHandler.class}
            , blockHandler = "handlerException"
            , fallbackClass = {GlobalFallback.class}
            , fallback = "fallbackException"
            // 异常忽略
            , exceptionsToIgnore = {IllegalArgumentException.class}
    )
    public ResponseEntity<String> printDd() {
        return ResponseEntity.ok("print dd!");
    }

    public static class GlobalBlockHandler {
        public static ResponseEntity<String> handlerException(BlockException e) {
            log.error(e.getMessage(), e);
            return ResponseEntity.ok("自定义handlerException！" + e.getMessage());
        }
    }

    public static class GlobalFallback {
        public static ResponseEntity<String> fallbackException() {
            return ResponseEntity.ok("自定义 fallbackException！");
        }
    }

}
